class YPromise {
    constructor(executor) {
        this.result = undefined
        this.status = "pending"
        // 收集器，发布订阅模式
        this.collector = []
        // 执行器立即执行
        executor(this.resolve, this.reject)
    }
    resolve = (res) => {
        if (this.status !== "pending") return
        this.status = "fulfilled"
        this.result = res
        this.collector.forEach(item => {
            item.successCB & item.successCB()
        })
    }
    reject = (err) => {
        if (this.status !== "pending") return
        this.status = "rejected"
        this.result = err
        this.collector.forEach(item => {
            item.failCB && item.failCB()
        })
    }
    then = (successCB, failCB) => {
        return new YPromise((resolve, reject) => {
            if (this.status === "fulfilled") {
                setTimeout(() => {
                    const returnValue = successCB && successCB(this.result)
                    isYPromise(resolve, reject, returnValue)
                });
            }
            if (this.status === "rejected") {
                setTimeout(() => {
                    const returnValue = failCB && failCB(this.result)
                    isYPromise(resolve, reject, returnValue)
                });
            }
            // 异步问题处理，发布订阅
            if (this.status === "pending") {
                this.collector.push({
                    successCB: () => {
                        const returnValue = successCB && successCB(this.result)
                        isYPromise(resolve, reject, returnValue)
                    },
                    failCB: () => {
                        const returnValue = failCB && failCB(this.result)
                        isYPromise(resolve, reject, returnValue)
                    }
                })
            }
        })
    }
}

function isYPromise(resolve, reject, returnValue) {
    // 判断返回值是否是YPromise的实例
    if (returnValue instanceof YPromise) {
        returnValue.then(res => {
            resolve(res)
        }, err => {
            reject(err)
        })
    } else {
        resolve(returnValue)
    }
}